package com.lxhll.personnel.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lxhll.personnel.common.EmailUtils;
import com.lxhll.personnel.core.P;
import com.lxhll.personnel.dao.EmployeeDao;
import com.lxhll.personnel.entity.Employee;
import com.lxhll.personnel.entity.EmployeeRole;
import com.lxhll.personnel.entity.Probation;
import com.lxhll.personnel.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * (Employee)表服务实现类
 *
 * @author makejava
 * @since 2021-07-18 15:06:39
 */
@Service("employeeService")
public class EmployeeServiceImpl extends ServiceImpl<EmployeeDao, Employee> implements EmployeeService {
    @Autowired
    private ProbationService probationService;
    @Autowired
    private DepartmentService departmentService;
    @Autowired
    private PositionService positionService;
    @Autowired
    private EmployeeRoleService employeeRoleService;

    @Autowired
    private EmailUtils eMailUtils;
    @Autowired
    private TemplateEngine templateEngine;

    @Override
    public IPage<Map<String, Object>> queryEmployee(Map<String, Object> params) {
        // 封装基本信息
        return this.baseMapper.queryEmployee(P.page(params), params);
        // QueryWrapper<Employee> wrapper=new QueryWrapper<>();
        // // for()

    }

    @Override
    public IPage<Employee> pageEmployee(Map<String, Object> params) {
        //查询员工列表,可以按照员工编号，姓名，身份证，岗位，部门等等多个条件查询
        QueryWrapper<Employee> wrapper=new QueryWrapper<>();
        addWrapper(params,wrapper);
        IPage<Employee> employeePage=this.page(P.page(params), wrapper.orderByDesc("entry_date"));
        //封装数据，给非sql字段赋值，多次查询部门，岗位，应使用redis
        for(Employee employee:employeePage.getRecords()){
            wrapperEmployee(employee);
        }
        return employeePage;
    }

    /**
     * 根据id获取用户
     * @param id
     * @return
     */
    @Override
    public Employee getEmployeeById(Integer id) {
        // 封装详细信息，包括试用期信息与其角色
        Employee employee=this.baseMapper.selectById(id);
        wrapperEmployee(employee);
        return employee;
    }

    /**
     * 根据员工姓名获取员工
     * @param name
     * @return
     */
    @Override
    public Employee getEmployeeByName(String name) {
        // 封装详细信息，包括试用期信息与角色
        Employee employee=this.baseMapper.selectOne(new QueryWrapper<Employee>().eq("name",name));
        wrapperEmployee(employee);
        return employee;
    }

    @Override
    public Employee getResignEmployeeById(Integer id) {
        Employee employee=this.baseMapper.getResignEmployeeById(id);
        wrapperEmployee(employee);
        return employee;
    }

    /**
     * 更新员工实体
     * @param employee
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateEmployeeById(Employee employee) {
        // 更新员工普通信息
        //若传来的密码不为空，对密码进行md5加密
        if(employee.getPassword()!=null&&employee.getPassword().length()>0){
            employee.setPassword(DigestUtils.md5DigestAsHex(employee.getPassword().getBytes()));
        }
        this.updateById(employee);
        //如果有重新分配角色，，要先删除旧关系，再根据前端传来的分配的ischeck——>role_id角色集合，插入员工-角色表
        if(employee.getIsCheckRole()!=null){
            employeeRoleService.remove(new QueryWrapper<EmployeeRole>().eq("employee_id",employee.getId()));
            //添加新关系
            List<EmployeeRole> erList=new ArrayList<>();
            for(Integer rid : employee.getIsCheckRole()){
                EmployeeRole er=new EmployeeRole();
                er.setEmployeeId(employee.getId());
                er.setRoleId(rid);
                erList.add(er);
            }
            employeeRoleService.saveBatch(erList);
        }

        return true;
    }

    /**
     * 更新员工试用期信息
     * @param employee
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateProbationEmployeeById(Employee employee) {
        // 更新员工实习期信息
        Probation probation = employee.getProbation();
        probation.setDealDate(LocalDate.now());
        System.out.println("试用期信息："+probation);
        probationService.updateProbationById(probation);
        // 如果是转正，就要更改员工类型了
        if(probation.getStatus().equals("转正")){
            employee.setType("正式工");
            this.updateById(employee);
        }
        return true;
    }

    /**
     * 员工入职
     * @param employee
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveEmployee(Employee employee) {
        // 插入员工与试用期信息
        //对密码进行md5加密
        String password=employee.getPassword();
        employee.setPassword(DigestUtils.md5DigestAsHex(password.getBytes()));
        this.save(employee);
        //如果有分配角色，，根据前端传来的分配的ischeck——>role_id角色集合，插入员工-角色表
        List<EmployeeRole> erList=new ArrayList<>();
        for(Integer rid : employee.getIsCheckRole()){
            EmployeeRole er=new EmployeeRole();
            er.setEmployeeId(employee.getId());
            er.setRoleId(rid);
            erList.add(er);
        }
        employeeRoleService.saveBatch(erList);
        // 如果是实习期员工，插入实习期信息
        if (employee.getType().contains("实习")) {
            Probation probation = employee.getProbation();
            probation.setEmployeeId(employee.getId());
            probation.setStatus("正常");
            probationService.save(probation);
            System.out.println(probation);
        }
        //如果员工有邮箱，就发入职邮件
        if(employee.getEmail()!=null){
            sendEMail(employee.getId());
        }

        return true;
    }

    /**
     * 员工离职，逻辑删除员工
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeEmployeeByIds(Integer[] ids) {
        QueryWrapper<Probation> wrapper = new QueryWrapper<>();
        this.removeByIds(Arrays.asList(ids));
        //1.如果是实习员工，删除实习试用期信息
        for (Integer id : ids) {
            probationService.remove(wrapper.eq("employee_id", id));
            wrapper.clear();
        }

        //2.删除角色关系  DELETE FROM sys_user_role WHERE (user_id = ?)
        for(Integer id : ids){
            employeeRoleService.remove(new QueryWrapper<EmployeeRole>().eq("employee_id", id));
        }
        return true;
    }



    /**
     * 封装员工信息
     * @param employee
     */
    private void wrapperEmployee(Employee employee){
        //显示部门名称
        employee.setDepartmentName(departmentService.getDepartmentById(employee.getDepartmentId()).getName());
        //显示岗位名称
        employee.setPositionName(positionService.getPositionById(employee.getPositionId()).getName());
        //封装角色信息
        employee.setRoleList(employeeRoleService.getRoleByEmployeeId(employee.getId()));
        //如果是实习生，封装他的实习信息
        if(employee.getType().contains("实习")){
            employee.setProbation(probationService.getProbationByEmployeeId(employee.getId()));
        }
    }

    /**
     *封装wrapper，构造条件查询
     * @param params
     */
    private void addWrapper(Map<String ,Object> params, QueryWrapper<Employee> queryWrapper){
        //查询员工列表,可以按照员工编号，姓名，身份证，岗位，部门等等多个条件查询
        for(String key:params.keySet()){
            if("pagesize".equals(key) || "pagenum".equals(key)){
                continue;
            }
            if(params.get(key)==null || "".equals(params.get(key))){
                continue;
            }
            if("id".equals(key)){
                queryWrapper.eq("id",params.get(key));
            }
            if("departmentId".equals(key)){
                queryWrapper.eq("department_id",params.get(key));
            }
            if("positionId".equals(key)){
                queryWrapper.eq("position_id",params.get(key));
            }
            if("idNumber".equals(key)){
                queryWrapper.eq("id_number",params.get(key));
            }
            if("startDate".equals(key)){
                queryWrapper.ge("entry_date",params.get(key));
            }
            if("endDate".equals(key)){
                queryWrapper.le("entry_date",params.get(key));
            }
            if("name".equals(key)){
                queryWrapper.like("name",params.get(key));
            }
            if("type".equals(key)){
                queryWrapper.like("type",params.get(key));
            }

        }
    }

    /**
     * 入职时，根据员工id，发送入职邮件
     * @param id
     */
    public void sendEMail(Integer id) {
        String subject = "员工入职通知";
        //thymeleaf的Context
        Employee employee=this.getEmployeeById(id);
        Context context = new Context();
        context.setVariable("employee",employee);
        String emailContext=templateEngine.process("email/emailEmployee",context);
        eMailUtils.sendEmail(employee.getEmail(),subject,emailContext);
    }

}
